import Layer from '../../core/Layer';
import GannFanLayer from './GannFanLayer';
import GoldLineLayer from './GoldLineLayer';
import HorizontalLayer from './HorizontalLayer';
import SegmentLayer from './SegmentLayer';
import StraightLayer from './StraightLayer';
import Point from '../../core/Point';
import Event from '../../event/Event';
import GoldRingLayer from './GoldRingLayer';
import GoldTimeLayer from './GoldTimeLayer';
import GegressionLayer from './GegressionLayer';
import GannBoxLayer from './GannBoxLayer';
import PeriodLayer from './PeriodLayer';


let uuid = 1;
function UUID() {
    const target = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
    return target.replace(/[x]/g, (c) => {
        const r = Math.random() * 16 | 0,
            v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

export default class extends Layer {
    constructor(canvas, style) {
        super(canvas, style);
        this.xStep = style.xStep || 0;
        this.yStep = style.yStep || 0;
        this.start = style.start || 0;
        this.end = style.end || 0;
        this.max = style.max || 0;
        this.min = style.min || 0;
        this.xAxis = style.xAxis || [];
        this.lines = style.lines || [];
        this.onLineMove = style.onLineMove;
        this.onLineMoved = style.onLineMoved;
        this.selectedLine = null;
    }

    /**
     * 查找某个日期的下标
     * @param date
     * @param data
     * @returns {number|*}
     */
    findIndex(date, data) {
        if (parseInt(date) > parseInt(data[data.length - 1])) {
            let shift = Math.round(
                (parseInt(date) - parseInt(data[data.length - 1]))
                / (parseInt(data[data.length - 2]) - parseInt(data[data.length - 3]))
            ) + data.length;
            return shift;
        }
        let cur = parseInt(date);
        for(let i = 1; i < data.length; i++) {
            if (cur >= parseInt(data[i - 1]) && cur <= parseInt(data[i])) {
                return i;
            }
        }
    }

    /**
     * 清除选中线条
     */
    clearSelected() {
        for(let i = 0; i < this.lines.length; i++) {
            this.lines[i].isSelected = false;
        }
    }

    make() {
        if (this.locked) {
            return;
        }
        this.clearEventListener();
        this.childs.splice(0, this.childs.length);
        for (let i = 0; i < this.lines.length; i++) {
            const shift1 = this.findIndex(this.lines[i].point1.date, this.xAxis);
            const shift2 = this.findIndex(this.lines[i].point2.date, this.xAxis);
            console.log('111', shift1, this.start, this.xStep);
            const x1 = (shift1 - this.start) * this.xStep;
            const x2 = (shift2 - this.start) * this.xStep;
            const uuid = this.lines[i].uuid !== undefined ? this.lines[i].uuid : UUID();
            let line = null;
            if (this.lines[i].type === 1) {
                console.log('draw line 1');
                // 直线
                line = new StraightLayer(this.canvas, {
                    uuid,
                    width: this.width,
                    height: this.height,
                    color: this.lines[i].color,
                    position: new Point(x1, (this.lines[i].point1.price - this.min) * this.yStep),
                    point2: new Point(x2, (this.lines[i].point2.price - this.min) * this.yStep),
                });
            }
            else if (this.lines[i].type === 2) {
                // 线段
                line = new SegmentLayer(this.canvas, {
                    uuid,
                    width: this.width,
                    height: this.height,
                    color: this.lines[i].color,
                    point1: new Point(x1, (this.lines[i].point1.price - this.min) * this.yStep),
                    point2: new Point(x2, (this.lines[i].point2.price - this.min) * this.yStep),
                });
            }
            else if (this.lines[i].type === 3) {
                // 水平线
                line = new HorizontalLayer(this.canvas, {
                    uuid,
                    width: this.width,
                    height: this.height,
                    color: this.lines[i].color,
                    position: new Point(x1, (this.lines[i].point1.price - this.min) * this.yStep),
                    content: this.lines[i].point1.price,
                });
            }
            else if (this.lines[i].type === 4) {
                const maxValue = this.lines[i].point1.price > this.lines[i].point2.price
                    ? this.lines[i].point1.price
                    : this.lines[i].point2.price;
                const minValue = this.lines[i].point1.price < this.lines[i].point2.price
                    ? this.lines[i].point1.price
                    : this.lines[i].point2.price;
                // 黄金分割线
                line = new GoldLineLayer(this.canvas, {
                    uuid,
                    width: this.width,
                    height: this.height,
                    color: this.lines[i].color,
                    point1: new Point(x1, (this.lines[i].point1.price - this.min) * this.yStep),
                    point2: new Point(x2, (this.lines[i].point2.price - this.min) * this.yStep),
                    maxValue,
                    minValue,
                    mesures: [-0.618, -0.382, 0, 0.236, 0.382, 0.5, 0.618, 0.809, 1, 1.382, 1.618],
                });
            }
            else if (this.lines[i].type === 5) {
                // 江恩线
                line = new GannFanLayer(this.canvas, {
                    uuid,
                    width: this.width,
                    height: this.height,
                    color: this.lines[i].color,
                    position: new Point(x1, (this.lines[i].point1.price - this.min) * this.yStep),
                    point2: new Point(x2, (this.lines[i].point2.price - this.min) * this.yStep),
                });
            }
            else if (this.lines[i].type === 6) {
                // 黄金分割环
                line = new GoldRingLayer(this.canvas, {
                    uuid,
                    width: this.width,
                    height: this.height,
                    color: this.lines[i].color,
                    point1: new Point(x1, (this.lines[i].point1.price - this.min) * this.yStep),
                    point2: new Point(x2, (this.lines[i].point2.price - this.min) * this.yStep),
                    mesures: [0.236, 0.382, 0.5, 0.618, 0.809, 1, 1.382, 1.618, 2, 1.382],
                    colors: [
                        '#7EF37E', '#6EF38E', '#AEE73E', '#FEE73E', '#FE973E', '#FE44BE',
                        '#FD473E', '#9EE7FE', '#CEE79E', '#AE173E', '#AE66FE', '#AE171E'
                    ]
                });
                console.log('ring===>', line);
            }
            else if (this.lines[i].type === 7) {
                // 时间黄金分割
                line = new GoldTimeLayer(this.canvas, {
                    uuid,
                    width: this.width,
                    height: this.height,
                    color: this.lines[i].color,
                    point1: new Point(x1, (this.lines[i].point1.price - this.min) * this.yStep),
                    point2: new Point(x2, (this.lines[i].point2.price - this.min) * this.yStep),
                    mesures: [0.236, 0.382, 0.5, 0.618, 0.809, 1, 1.382, 1.618, 2, 1.382],
                });
            }
            else if (this.lines[i].type === 8) {
                // 回归线
                const shift3 = this.findIndex(this.lines[i].point3.date, this.xAxis);
                const x3 = (shift3 - this.start) * this.xStep;
                line = new GegressionLayer(this.canvas, {
                    uuid,
                    width: this.width,
                    height: this.height,
                    color: this.lines[i].color,
                    point1: new Point(x1, (this.lines[i].point1.price - this.min) * this.yStep),
                    point2: new Point(x2, (this.lines[i].point2.price - this.min) * this.yStep),
                    point3: new Point(x3, (this.lines[i].point2.price - this.min) * this.yStep),
                });
            }
            else if (this.lines[i].type === 9) {
                // 甘氏箱
                line = new GannBoxLayer(this.canvas, {
                    uuid,
                    width: this.width,
                    height: this.height,
                    color: this.lines[i].color,
                    point1: new Point(x1, (this.lines[i].point1.price - this.min) * this.yStep),
                    point2: new Point(x2, (this.lines[i].point2.price - this.min) * this.yStep),
                });
            }
            else if (this.lines[i].type === 10) {
                // 周期线
                line = new PeriodLayer(this.canvas, {
                    uuid,
                    width: this.width,
                    height: this.height,
                    color: this.lines[i].color,
                    point1: new Point(x1, (this.lines[i].point1.price - this.min) * this.yStep),
                    point2: new Point(x2, (this.lines[i].point2.price - this.min) * this.yStep),
                });
            }
            line.addEventListener(Event.EVENT_TAP, (e) => {
                const index = this.lines.findIndex(vo => vo.uuid === uuid);
                this.clearSelected();
                this.lines[index].isSelected = true;
                this.make();
                this.canvas.paint();
                this.onSelected && this.onSelected(uuid);
            });
            this.addChild(line);
            line.setSelected(!!this.lines[i].isSelected);
            this.lines[i].uuid = uuid;
            line.onLineMove =  (line) => {
                const shift1 = Math.round(line.circle1.position.x / this.xStep + this.start);
                const shift2 = Math.round(line.circle2.position.x / this.xStep + this.start);
                const y1 = line.circle1.position.y / this.yStep + this.min;
                const y2 = line.circle2.position.y / this.yStep + this.min;
                let x1 = 0;
                let x2 = 0;
                const xTimeDelta = Number(this.xAxis[this.xAxis.length - 2])
                    - Number(this.xAxis[this.xAxis.length - 3]);
                if (shift1 > this.xAxis.length) {
                    x1 = xTimeDelta * (shift1 - this.xAxis.length) + Number(this.xAxis[this.xAxis.length - 1]);
                } else if (shift1 < 0) {
                    x1 = Number(this.xAxis[0]) + xTimeDelta * shift1;
                } else {
                    x1 = this.xAxis[shift1];
                }
                if (shift2 > this.xAxis.length) {
                    x2 = xTimeDelta * (shift2 - this.xAxis.length) + Number(this.xAxis[this.xAxis.length - 1]);
                } else if (shift2 < 0) {
                    x2 = Number(this.xAxis[0]) + xTimeDelta * shift2;
                } else {
                    x2 = this.xAxis[shift2];
                }
                const index = this.lines.findIndex(vo => vo.uuid === line.uuid);
                if (index >= 0) {
                    this.lines[index].point1.date = x1;
                    this.lines[index].point1.price = y1;
                    this.lines[index].point2.date = x2;
                    this.lines[index].point2.price = y2;
                    if (line instanceof GegressionLayer) {
                        const shift3 = Math.round(line.circle3.position.x / this.xStep + this.start);
                        const y3 = line.circle3.position.y / this.yStep + this.min;
                        let x3 = 0;
                        if (shift3 > this.xAxis.length) {
                            x3 = xTimeDelta * (shift3 - this.xAxis.length) + Number(this.xAxis[this.xAxis.length - 1]);
                        } else if (shift1 < 0) {
                            x3 = Number(this.xAxis[0]) + xTimeDelta * shift3;
                        } else {
                            x3 = this.xAxis[shift3];
                        }
                        this.lines[index].point3.date = x3;
                        this.lines[index].point3.price = y3;
                    }
                }
                this.onLineMove && this.onLineMove(line);
            };
            line.onLineMoved = (line) => {
                const index = this.lines.findIndex(vo => vo.uuid === line.uuid);
                this.onLineMoved && this.onLineMoved(line, this.lines[index]);
            }
        }
        console.log('make', this);
    }
}
